package thread;

/** date:2023-2-12
 * 请完成以下多线程编程：顺序打印
 * 有三个线程，线程名称分别为：a，b，c。
 * 每个线程打印自己的名称。需要让他们同时启动，并按 c，b，a的顺序打印
 */
public class Demo5 {
    public static void main1(String[] args) {
        // 创建一个锁
        Object loker = new Object();

        Thread c = new Thread(() -> {
            System.out.println("c");
        });
        Thread b = new Thread(() -> {
            try {
                c.join(); // 等待线程c执行完再执行b
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("b");
        });
        Thread a = new Thread(() -> {
            try {
                b.join(); // 等待线程b执行完再执行a
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("a");
        });
        a.start();
        b.start();
        c.start();
    }

    public static void main(String[] args) throws InterruptedException {
        // 创建两个锁
        Object loker1 = new Object();
        Object loker2 = new Object();

        Thread t1 = new Thread(() -> {
            System.out.println("c");
            synchronized (loker1) {
                loker1.notify();
            }
        });
        Thread t2 = new Thread(() -> {
            synchronized (loker1) {
                try {
                    loker1.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("b");

            synchronized (loker2) {
                loker2.notify(); // 打印完 b 之后通知下边的线程可以获取锁了
            }
        });
        Thread t3 = new Thread(() -> {
            synchronized (loker2) {
                try {
                    loker2.wait(); // 运行线程3的时候运行到这里进行阻塞
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("a");
        });

        t2.start(); // b
        t3.start(); // a
        // 加入 sleep 为了先让 t2,t3 的 wait 执行了，然后去执行 t1 的 notify
        Thread.sleep(100);
        t1.start(); // c
    }
}
